unit uniEnemyAircraft_Boss00;

interface

uses
  uniEnemyAircraft,
  Classes;

type
  { EnemyAircraft_Boss00 }

  EnemyAircraft_Boss00 = class(EnemyAircraft)
  public
    constructor Create(et: EnemyType; p: array of Single; randFact: Single = 1.0);
    destructor Destroy; override;

    procedure update; override;
    procedure init; overload; override;
    procedure init(p: array of Single; randFact: Single = 1.0); overload; override;
    procedure move; override;
  end;


implementation

uses
  uniConfig,
  uniGlobal;

{ EnemyAircraft_Boss00 }

constructor EnemyAircraft_Boss00.Create(et: EnemyType; p: array of Single; randFact: Single);
begin
  inherited Create(et, p, randFact);
  init(p, randFact);
end;

destructor EnemyAircraft_Boss00.Destroy;
begin

  inherited;
end;

procedure EnemyAircraft_Boss00.init;
begin
  inherited init;
end;

procedure EnemyAircraft_Boss00.init(p: array of Single; randFact: Single);
begin
  inherited init(p, randFact);

  damage := -10000.0 * gameSkill;
  baseDamage := damage;

  size[0] := 3.5;
  size[1] := 2.275;
  collisionMove := 0.05;
  vel[1] := 0.02;
end;

procedure EnemyAircraft_Boss00.move;
var
  _config: Config;
  hpos: PSingle;
  diff: array[0..1] of Single;
  approachDist: Single;
begin
  _config := uniConfig.instance;
  if Boolean(target) then
  begin
    hpos := target.getPos;
  end
  else
  begin
    hpos := @pos;
  end;

  diff[0] := hpos^ - pos[0]; Inc(hpos);
  diff[1] := hpos^ - pos[1];

  approachDist := 7.0 * (2.0 - uniGlobal.gameSkill);
  if Abs(diff[1]) < (approachDist + 0.0 * Sin(uniGlobal.frame * 0.05)) then
  begin
    diff[1] := diff[1] * diff[1] / approachDist;
  end;
  diff[0] := diff[0] + 5.0 * Sin(age * 0.1);
  lastMoveX := (0.98 * lastMoveX)  + (0.0005 * uniGlobal.gameSkill * diff[0]);
  lastMoveY := (0.98 * lastMoveY)  + (0.001 * uniGlobal.gameSkill * diff[1]);
  pos[0] := pos[0] + uniGlobal.speedAdj * (lastMoveX);
  pos[1] := pos[1] + uniGlobal.speedAdj * (lastMoveY + vel[1]);

  if pos[0] < -_config.screenBoundX then pos[0] := -_config.screenBoundX;
  if pos[0] > _config.screenBoundX then pos[0] := _config.screenBoundX;




end;

//-- NOTE: Many of the firing rates are not adjusted by game->speedAdj
//-- so they will not be totally correct. Should be close enough for jazz, though.
//----------------------------------------------------------

procedure EnemyAircraft_Boss00.update;
var
  v: array[0..2] of Single;
  hpos: array of Single;
  a: Single;
  b: single;
  dist: Single;
  ammoSpeed: Single;

  s: Single;

  p: array[0..2] of Single;
begin
  //-- update age
  Inc(age);
  Dec(shootInterval);

  pos[0] := pos[0] + secondaryMove[0] * uniGlobal.speedAdj;
  pos[1] := pos[1] + secondaryMove[1] * uniGlobal.speedAdj;
  s := (1.0 - uniGlobal.speedAdj) + (uniGlobal.speedAdj * 0.7);
  secondaryMove[0] := secondaryMove[0] * s;
  secondaryMove[1] := secondaryMove[1] * s;
  move;

  p[0] := pos[0];
  p[1] := pos[1];
  p[2] := pos[2];

  if Abs(a) < 1.6 then //-- big center gun
  begin
    v[1] := -0.6;
    p[1] := Pos[1] - 1.7;
    uniGlobal._enemyAmmo.addAmmo(3, p, v);
  end;

  if not Boolean(age mod 5) then //-- side cannons
  begin
    Inc(shootSwap);
    shootSwap := shootSwap mod 15;
    if shootSwap < 6 then
    begin
      v[1] := -0.2;
      p[1] := pos[1] - 1.9;
      p[0] := pos[0] + 2.0 + ((shootSwap mod 3) * 0.4);
      uniGlobal._enemyAmmo.addAmmo(0, p, v);
      p[0] := Pos[0] - 2.0 - ((shootSwap mod 3) * 0.4);
      uniGlobal._enemyAmmo.addAmmo(0, p, v);
    end;
  end;

  if not Boolean((age - 1) mod 7) then
  begin
    dist := Abs(a) + Abs(b);
    shootVec[0] := ammoSpeed * a / dist;
    shootVec[1] := ammoSpeed * b / dist;
  end;

  //if not Boolean((age / 200) mod 2) then //-- omni shooters
  if not Boolean(Round(age / 200) mod 2) then //-- omni shooters
  begin
    if (not Boolean(Round(age / 100) mod 2)) then
    begin
      if (not Boolean(Round(age / 50) mod 2)) then
      begin
        p[1] := pos[1] - 0.45;
        p[0] := pos[0] - 1.1;
        //game - > enemyAmmo - > addAmmo(1, p, shootVec);
        uniGlobal._enemyAmmo.addAmmo(1, p, shootVec);
        p[0] := pos[0] + 1.1;
        //game - > enemyAmmo - > addAmmo(1, p, shootVec);
        uniGlobal._enemyAmmo.addAmmo(1, p, shootVec);
      end;
      preFire := (age mod 100) / 100.0;
    end
    else
    begin
      if (not Boolean(age mod 10)) then
      begin
        p[1] := pos[1] - 0.45;
        b := hpos[1] - p[1];
        p[0] := pos[0] - 1.1;
        a := hpos[0] - p[0];
        dist := Abs(a) + Abs(b);
        shootVec[0] := 2.0 * ammoSpeed * a / dist;
        shootVec[1] := 2.0 * ammoSpeed * b / dist;
        //game - > enemyAmmo - > addAmmo(2, p, shootVec);
        uniGlobal._enemyAmmo.addAmmo(2, p, shootVec);
        p[0] := pos[0] + 1.1;
        a := hpos[0] - p[0];
        dist := Abs(a) + Abs(b);
        shootVec[0] := 2.0 * ammoSpeed * a / dist;
        shootVec[1] := 2.0 * ammoSpeed * b / dist;
        //game - > enemyAmmo - > addAmmo(2, p, shootVec);
        uniGlobal._enemyAmmo.addAmmo(2, p, shootVec);
        preFire := preFire - 0.4;
        if (preFire < 0.0) then
          preFire := 0.0;
      end
      else
      begin
        preFire := preFire + 0.035;
      end;
    end;
  end
  else
  begin
    preFire := 0.0;
  end;
end;

end.

